home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 1.iso / DEMON / GNU / PDMake / c / make < prev    next >
Text File  |  1995-04-09  |  6KB  |  274 lines

  1. /* > C.Make
  2.  *
  3.  * $Id: c.make 1.8 95/07/15 13:20:02 root Exp $
  4.  *
  5.  * $Log:    c.make $
  6.  * Revision 1.8  95/07/15  13:20:02  root
  7.  * root, go away
  8.  * 
  9.  * Revision 1.7  95/07/15  13:18:11  root
  10.  * Added filename editing in all system() , modtime & touch calls
  11.  * so RISCOS names work.
  12.  * 
  13.  * Revision 1.6  95/04/19  22:51:45  root
  14.  * When releasing, get the code right ??
  15.  *
  16.  * Revision 1.5  95/04/19  22:44:39  root
  17.  * Checked in for release
  18.  *
  19.  * Revision 1.4  95/04/19  22:34:59  root
  20.  * Altered the system[] call to operate
  21.  * correctly on error return
  22.  *
  23.  * Revision 1.3  95/04/18  21:48:29  root
  24.  * *** empty log message ***
  25.  *
  26.  * Revision 1.2  95/04/18  21:42:07  root
  27.  * Tidied for release
  28.  *
  29.  *
  30.  * Do the actual making for make
  31.  */
  32. #include "unistd.h"
  33. #include "h.h"
  34. /* Used to get os_file for 'touch' */
  35. #include <sys/os.h>
  36.  
  37. /*
  38.  * Exec a shell that returns exit status correctly (/bin/esh).
  39.  * The standard EON shell returns the process number of the last
  40.  * async command, used by the debugger (ugg).
  41.  * [exec on eon is like a fork+exec on unix]
  42.  */
  43. void dosh(char *string,bool ignore)
  44. {
  45.   int rc = 0;
  46.   char * ret ;
  47.   char * cmdline;
  48.   /* need to strip the command line down into the shortest form possible */
  49.   cmdline = do_RO_names(string ); /* and do RISCOS path editing */
  50.  
  51.   rc =  system (cmdline);
  52.   /* Unless ignoring return codes, bomb on non-zero return */
  53.   if (!ignore && rc )
  54.     exit(rc);
  55. }
  56.  
  57.  
  58.  
  59.  
  60. /*
  61.  * Do commands to make a target
  62.  */
  63. void
  64. docmds1(struct name *np, struct line *lp)
  65.  
  66. {
  67.    bool     ssilent;
  68.    bool     signore;
  69.    register char *    q;
  70.    register char *    p;
  71.    register struct cmd *   cp;
  72.  
  73.  
  74.    for (cp =(lp->l_cmd); cp!=NULL ; cp = (cp->c_next))
  75.    {
  76.  
  77.       strcpy(str1, cp->c_cmd);
  78.       expand(str1);
  79.       q = str1;
  80.       ssilent = silent;
  81.       signore = ignore;
  82.       while ((*q == '@') || (*q == '-'))
  83.       {
  84.     if (*q == '@')     /*  Specific silent  */
  85.        ssilent = TRUE;
  86.     else     /*  Specific ignore  */
  87.        signore = TRUE;
  88.     q++;     /*  Not part of the command  */
  89.       }
  90.  
  91.       if (!domake)
  92.         ssilent = 0; /* shut up if making */
  93.  
  94. /*
  95.       if (!ssilent)
  96.         fputs("Need to do: ", stdout);
  97. */
  98.       for (p=q; *p; p++)
  99.       {
  100.        if (*p == '\n' && p[1] != '\0')
  101.        {
  102.        *p = ' ';
  103.        if (!ssilent)
  104.           fputs("\\\n", stdout);
  105.         }
  106.     else if (!ssilent)
  107.        putchar(*p);
  108.       }
  109.       if (!ssilent)
  110.     putchar('\n');
  111.  
  112.       if (domake)
  113.       {        /*  Get the shell to execute it  */
  114.       dosh(q,signore );
  115.       }
  116.    }
  117. }
  118.  
  119. void
  120. docmds(struct name *np)
  121. {
  122.    register struct line *  lp;
  123.  
  124.    for (lp = np->n_line; lp; lp = lp->l_next)
  125.       docmds1(np, lp);
  126. }
  127.  
  128.  
  129.  
  130. /*
  131.  * Get the modification time of a file.  If the first
  132.  * doesn't exist, it's modtime is set to 0.
  133.  */
  134. void
  135. modtime(struct name * np)
  136. {
  137.   char * RO_name;
  138.   struct stat StatBuf;
  139.   StatBuf.st_mode = 0L;  /* zero mode so you can tell that its a file */
  140.   RO_name = do_RO_names(np->n_name);
  141.   stat (RO_name, &StatBuf); /* Unix Stat */
  142.  
  143.    if ((StatBuf.st_mode & S_IFREG)==0) /* IFREG regular file ? man 5 stat ?*/
  144.      np->n_time = 0L;
  145.    else
  146.      np->n_time = StatBuf.st_ctime;
  147. /*   printf("File is '%s' : mode %010o time: %d\n",
  148.           RO_name,StatBuf.st_mode,np->n_time);
  149. */
  150. }
  151.  
  152.  
  153. /*
  154.  * Update the mod time of a file to now.
  155.  * RISCOS specific routine as there isnt one in UnixLib.
  156.  */
  157. void
  158. touch(struct name *np)
  159. {
  160.   char * RO_name;
  161.   if (!domake || !silent)
  162.     printf("    touch(%s)\n", np->n_name);
  163.  
  164.   if (domake)
  165.   {
  166.     RO_name = do_RO_names(np->n_name);
  167.     os_file(9,RO_name,0); /* set the stamp on the file */
  168.   }
  169. }
  170.  
  171. void make1(struct name *np, struct line * lp,struct depend * qdp);
  172. /*
  173.  * Recursive routine to make a target.
  174.  */
  175. int make(struct name *np, int level)
  176.  
  177. {
  178.    register struct depend *   dp;
  179.    register struct line *     lp;
  180.    register struct depend *   qdp;
  181.    time_t      dtime;
  182.    bool        didsomething;
  183.    didsomething = 0;
  184.    dtime = 1;
  185.  
  186. #ifdef debug
  187.    printf ("Make : %s\n",np->n_name);
  188. #endif
  189.  
  190.    if (np->n_flag & N_DONE)
  191.       return 0;
  192.  
  193.    if (!np->n_time)
  194.       modtime(np);  /*  Gets modtime of this file  */
  195.  
  196.    if (rules)
  197.    {
  198.       for (lp = np->n_line; lp; lp = lp->l_next)
  199.     if (lp->l_cmd)
  200.        break;
  201.       if (!lp)
  202.     dyndep(np);
  203.    }
  204.  
  205.    if (!(np->n_flag & N_TARG) && np->n_time == 0L)
  206.       fatal("Don't know how to make %s", np->n_name);
  207.  
  208.    for (qdp = (struct depend *)0, lp = np->n_line; lp; lp = lp->l_next)
  209.    {
  210.       for (dp = lp->l_dep; dp; dp = dp->d_next)
  211.       {
  212.       make(dp->d_name, level+1);
  213.        if (np->n_time < dp->d_name->n_time)
  214.        qdp = newdep(dp->d_name, qdp);
  215.     dtime = max(dtime, dp->d_name->n_time);
  216.       }
  217.       if (!quest && (np->n_flag & N_DOUBLE) && (np->n_time < dtime))
  218.         {
  219.         make1(np, lp, qdp);     /* free()'s qdp */
  220.         dtime = 1;
  221.         qdp = (struct depend *)0;
  222.         didsomething++;
  223.         }
  224.    }
  225.  
  226.    np->n_flag |= N_DONE;
  227.  
  228.    if (quest)
  229.    {
  230.       long  t;
  231.  
  232.       t = np->n_time;
  233.       time(&np->n_time);
  234.       return t < dtime;
  235.    }
  236.    else if (np->n_time < dtime && !(np->n_flag & N_DOUBLE))
  237.    {
  238.       make1(np, (struct line *)0, qdp);  /* free()'s qdp */
  239.       time(&np->n_time);
  240.    }
  241.    else if (level == 0 && !didsomething)
  242.       printf(MYNAME": '%s' is up to date\n", np->n_name);
  243.    return 0;
  244. }
  245.  
  246. void
  247. make1(struct name *np, struct line * lp,struct depend * qdp)
  248. {
  249.    register struct depend *   dp;
  250.  
  251.  
  252.    if (dotouch)
  253.       touch(np);
  254.    else
  255.    {
  256.       strcpy(str1, "");
  257.       for (dp = qdp; dp; dp = qdp)
  258.       {
  259.     if (strlen(str1))
  260.        strcat(str1, " ");
  261.     strcat(str1, dp->d_name->n_name);
  262.     qdp = dp->d_next;
  263.     free(dp);
  264.       }
  265.     setmacro("?", str1);
  266.     setmacro("@", np->n_name);
  267.     if (lp)    /* lp set if doing a :: rule */
  268.       docmds1(np, lp);
  269.     else
  270.       docmds(np);
  271.    }
  272. }
  273.  
  274.